import fs from "fs-extra";
import path from "path";
import { glob } from "glob";
import axios from "axios";

const ROOT_DIR = "src";
const OUTPUT_DIR = path.join(ROOT_DIR, "locales");
const LOCALES = ["zh", "en", "fr"]; // 添加法语
const USE_GPT_TRANSLATE = true;

const chineseReg =
  /(["'`>])([\u4e00-\u9fa5，。！？、“”‘’：；【】（）—《》\s]+)/g;

const SIMPLE_MAP = {
  欢迎回来: "welcome",
  系统设置: "settings",
  网络错误: "network_error",
  登录成功: "login_success",
  失败: "fail",
  返回: "back",
  用户: "user",
  标题: "title",
  保存: "save",
  取消: "cancel",
  提交: "submit",
  登录失败: "login_failed", // 添加法语键值对
  提交成功: "submit_success", // 添加法语键值对
};
// ---------------- 工具函数 ----------------
function setDeep(obj, keys, value) {
  const last = keys.pop();
  let ref = obj;
  for (const key of keys) {
    if (!ref[key]) ref[key] = {};
    ref = ref[key];
  }
  ref[last] = value;
}

function getDeep(obj, keys) {
  let ref = obj;
  for (const key of keys) {
    if (!ref[key]) return undefined;
    ref = ref[key];
  }
  return ref;
}

function hasKey(obj, keys) {
  let ref = obj;
  for (const k of keys) {
    if (!ref[k]) return false;
    ref = ref[k];
  }
  return true;
}

function toPinyinLite(str) {
  const map = {
    欢: "huan",
    迎: "ying",
    回: "hui",
    来: "lai",
    系: "xi",
    统: "tong",
    设: "she",
    置: "zhi",
  };
  return str
    .split("")
    .map((c) => map[c] || "x")
    .slice(0, 5)
    .join("_");
}

// ---------------- GPT 调用 ----------------
async function translateKey(cn) {
  console.log("🚀 ~ translateKey ~ key:", cn);
  try {
    const res = await axios.post("http://localhost:1234/v1/chat/completions", {
      model: "qwen/qwen3-4b-2507",
      messages: [
        {
          role: "system",
          content:
            "从中文生成一个简短的小写英文i18n键，用下划线连接，仅返回结果",
        },
        { role: "user", content: cn },
      ],
    });
    const data = res.data.choices[0].message.content
      .trim()
      .replace(/\s+/g, "_");
    console.log("🚀 ~ translateKey ~ key-en:", data);
    return data;
  } catch {
    console.error("大模型加载失败");
    return toPinyinLite(cn);
  }
}

async function translateValue(cn, language = "en") {
  // 语言支持动态选择
  console.log("🚀 ~ translateValue ~ cn:", cn, "lang:", language);
  try {
    const res = await axios.post("http://localhost:1234/v1/chat/completions", {
      model: "qwen/qwen3-4b-2507",
      messages: [
        {
          role: "system",
          content: `将中文翻译为简短的 ${language} i18n显示值，仅返回结果`,
        },
        { role: "user", content: cn },
      ],
    });
    const data = res.data.choices[0].message.content.trim();
    console.log(
      "🚀 ~ translateValue ~ cn:",
      cn,
      "lang:",
      language,
      "en:",
      data
    );
    return data;
  } catch {
    return SIMPLE_MAP[cn] || "";
  }
}

// ---------------- 路径 & Key ----------------
function toCamelCase(str) {
  return str.charAt(0).toLowerCase() + str.slice(1);
}

function getKeyPrefix(filePath) {
  // 获取相对路径
  let relative = path.relative(ROOT_DIR, filePath).split(path.sep).join("/");

  // 去掉 src/pages 或 pages
  relative = relative.replace(/^src\/pages\//, "").replace(/^pages\//, "");

  // 去掉扩展名
  relative = relative.replace(path.extname(relative), "");

  // 拆分层级
  const parts = relative.split("/").filter(Boolean);

  // 去掉 index
  if (parts[parts.length - 1] === "index") parts.pop();

  // 转为小驼峰
  const camelParts = parts.map((p) => toCamelCase(p));

  return camelParts.join(".");
}
async function generateKey(filePath, cn, zhData, usedKeys) {
  const prefix = getKeyPrefix(filePath);
  let baseKey =
    SIMPLE_MAP[cn] ||
    (USE_GPT_TRANSLATE ? await translateKey(cn) : toPinyinLite(cn));

  let key = prefix ? `${prefix}.${baseKey}` : baseKey;
  const keyParts = key.split(".");
  const parentKeys = keyParts.slice(0, -1);
  const lastKey = keyParts[keyParts.length - 1];

  const parentObj = getDeep(zhData, parentKeys) || {};

  // ✅ 如果同层已有同值，直接复用已有 key
  for (const [k, v] of Object.entries(parentObj)) {
    if (v === cn) {
      return [...parentKeys, k].join(".");
    }
  }

  // ✅ 如果 key 已存在但值不同，换个名字（简短地加编号）
  let count = 1;
  let newKey = lastKey;
  while (parentObj[newKey]) {
    count++;
    newKey = `${lastKey}_${count}`;
  }

  const finalKey = prefix ? `${prefix}.${newKey}` : newKey;
  usedKeys.add(finalKey);
  return finalKey;
}

// ---------------- 主流程 ----------------
async function run() {
  const zhFile = path.join(OUTPUT_DIR, "zh.json");
  const enFile = path.join(OUTPUT_DIR, "en.json");
  const frFile = path.join(OUTPUT_DIR, "fr.json"); // 法语文件

  const zhData = fs.existsSync(zhFile) ? fs.readJSONSync(zhFile) : {};
  const enData = fs.existsSync(enFile) ? fs.readJSONSync(enFile) : {};
  const frData = fs.existsSync(frFile) ? fs.readJSONSync(frFile) : {}; // 加载法语数据

  const usedKeys = new Set();

  const files = glob.sync(`${ROOT_DIR}/pages/**/*.tsx`); 
  let total = 0;

  for (const file of files) {
    let content = fs.readFileSync(file, "utf-8");
    let hasChange = false;
    let match;

    while ((match = chineseReg.exec(content))) {
      const cn = match[2].trim();
      if (!cn) continue;

      const key = await generateKey(file, cn, zhData, usedKeys);
      const keyParts = key.split(".");

      if (!hasKey(zhData, keyParts)) {
        setDeep(zhData, [...keyParts], cn);
        const en = USE_GPT_TRANSLATE
          ? await translateValue(cn, "en") // 英文翻译
          : SIMPLE_MAP[cn] || "";
        setDeep(enData, [...keyParts], en);

        const fr = USE_GPT_TRANSLATE
          ? await translateValue(cn, "fr") // 法语翻译
          : SIMPLE_MAP[cn] || "";
        setDeep(frData, [...keyParts], fr);
      }

      // 根据匹配上下文判断是否在引号中
      const before = content.slice(Math.max(0, match.index - 1), match.index);
      const after = content.slice(
        match.index + cn.length,
        match.index + cn.length + 1
      );

      if (/['"`=]/.test(before) && /['"`]/.test(after)) {
        // 在属性或字符串内 → 去掉引号
        content =
          content.slice(0, match.index - 1) +
          `{t('${key}')}` +
          content.slice(match.index + cn.length + 1);
      } else {
        // 普通文本（JSX 内） → 正常替换
        content = content.replace(cn, `{t('${key}')}`);
      }

      hasChange = true;
      total++;
    }

    if (hasChange) {
      fs.writeFileSync(file, content, "utf-8");
      console.log("🛠 已替换:", file);
    }
  }

  fs.ensureDirSync(OUTPUT_DIR);
  fs.writeJSONSync(zhFile, zhData, { spaces: 2 });
  fs.writeJSONSync(enFile, enData, { spaces: 2 });
  fs.writeJSONSync(frFile, frData, { spaces: 2 }); // 保存法语文件

  console.log(`✅ 完成：提取 ${total} 条中文，去重 + 增量写入成功`);
}

run();
